package com.wiseasy.smartpos.cashierdemo.util;

import android.util.Log;
import android.util.Xml;

import org.xmlpull.v1.XmlPullParser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class SAXParserUtils {

   private static final String TAG = SAXParserUtils.class.getSimpleName();

   private static final String TAG_AID = "AID Parameters";

   private static final String TAG_CAPK = "PublicKeys";

   private static final String TAG_RE_CAPK = "Revocation Capks";

   private static final String TAG_PAN_BLACK = "PAN Blacklists";

   private static final String TAG_PID = "PIDList";

   private static final String TAG_DRL = "DRLList";

   private static final String TAG_DEFAULT_PARAMETERS = "Default Parameters";

   private static final List<String> list_aid = new ArrayList<>();

   private static final List<String> list_capk = new ArrayList<>();

   private static final List<String> list_re_capk = new ArrayList<>();

   private static final List<String> list_pan_black = new ArrayList<>();

   private static final List<String> list_pid = new ArrayList<>();

   private static final List<String> list_drl = new ArrayList<>();

   private static final List<String> list_default_parameters = new ArrayList<>();

   private static int type;

   public static List<String> getAidList(InputStream is) throws Exception {
      if (list_aid.size() == 0) {
         sax2xml(is);
      }
      return list_aid;
   }

   public static List<String> getCapkList(InputStream is) throws Exception {
      if (list_capk.size() == 0) {
         sax2xml(is);
      }
      return list_capk;
   }

   public static List<String> getRevocationCapkList(InputStream is) throws Exception {
      if (list_re_capk.size() == 0) {
         sax2xml(is);
      }
      return list_re_capk;
   }

   public static List<String> getBlacklistPan(InputStream is) throws Exception {
      if (list_pan_black.size() == 0) {
         sax2xml(is);
      }
      return list_pan_black;
   }

   public static List<String> getPidList(InputStream is) throws Exception {
      if (list_pid.size() == 0) {
         sax2xml(is);
      }
      return list_pid;
   }

   public static List<String> getDrlList(InputStream is) throws Exception {
      if (list_drl.size() == 0) {
         sax2xml(is);
      }
      return list_drl;
   }

   public static List<String> getDefaultParameters(InputStream is) throws Exception {
      if (list_default_parameters.size() == 0) {
         sax2xml(is);
      }
      return list_default_parameters;
   }

   private static void sax2xml(InputStream is) throws Exception {
      String temp = "";
      XmlPullParser parser = Xml.newPullParser();
      parser.setInput(is, "utf-8");
      int eventType = parser.getEventType();
      while (eventType != XmlPullParser.END_DOCUMENT) {
         switch (eventType) {
            case XmlPullParser.START_TAG:
               String start_name = parser.getName();
               Log.v(TAG, "start_name: " + start_name);

               if ("map".equals(start_name)) {
                  temp = "";
               } else {
                  boolean isTlv = false;
                  int count = parser.getAttributeCount();
                  if (count == 2) {
                     String key = parser.getAttributeValue(0);
                     String[] keys = key.split("_");
                     //if (keys.length == 4) {
                     //AID_9F06
                     if (keys.length == 2) {
                        isTlv = true;
                        temp += keys[1];
                        Log.v(TAG, "key: " + keys[1]);
                     }
                     if (isTlv) {
                        isTlv = false;
                        String value = parser.getAttributeValue(1);
                        Log.v(TAG, "value: " + value);
                        int lenValue = value.length() / 2;
                        String strLen = lenValue < 0x10 ? ("0" + Integer.toHexString(lenValue)) : Integer.toHexString(lenValue);
                        if (lenValue < 127) {
                           temp += strLen + value;
                        } else if (lenValue < 255) {
                           temp += "81" + strLen + value;
                        } else {
                           temp += "82" + strLen + value;
                        }
                     }
                  } else {
                     String node = parser.getAttributeValue(0);
                     Log.v(TAG, "node: " + node);
                     if (TAG_AID.equals(node)) {
                        type = 0;
                        list_aid.clear();
                        Log.v(TAG, "type: " + type);
                     } else if (TAG_CAPK.equals(node)) {
                        type = 1;
                        list_capk.clear();
                        Log.v(TAG, "type: " + type);
                     } else if (TAG_RE_CAPK.equals(node)) {
                        type = 2;
                        list_re_capk.clear();
                        Log.v(TAG, "type: " + type);
                     } else if (TAG_PAN_BLACK.equals(node)) {
                        type = 3;
                        list_pan_black.clear();
                        Log.v(TAG, "type: " + type);
                     } else if (TAG_PID.equals(node)) {
                        type = 4;
                        list_pid.clear();
                        Log.v(TAG, "type: " + type);
                     } else if (TAG_DRL.equals(node)) {
                        type = 5;
                        list_drl.clear();
                        Log.v(TAG, "type: " + type);
                     }else if (TAG_DEFAULT_PARAMETERS.equals(node)) {
                        type = 6;
                        list_default_parameters.clear();
                        Log.v(TAG, "type: " + type);
                     }
                  }
               }
               break;

            case XmlPullParser.END_TAG:
               String end_name = parser.getName();
               Log.v(TAG, "end_name: " + end_name);
               if (!temp.isEmpty() && "map".equals(end_name)) {
                  switch (type) {
                     case 0:
                        list_aid.add(temp);
                        break;
                     case 1:
                        list_capk.add(temp);
                        break;
                     case 2:
                        list_re_capk.add(temp);
                        break;
                     case 3:
                        list_pan_black.add(temp);
                        break;
                     case 4:
                        list_pid.add(temp);
                        break;
                     case 5:
                        list_drl.add(temp);
                        break;
                     case 6:
                        list_default_parameters.add(temp);
                        break;
                     default:
                        break;
                  }
                  temp = "";
               }
               break;
            default:
               break;
         }
         eventType = parser.next();
      }
   }
}
